#include "stm32f10x.h"    
#include "freertos.h"
#include "task.h"
#include "queue.h"

#include "LED_Control.h"
#include "USART_SendString.h"
#include "USART_RecvString.h"

#include <string.h>

#define QUEUE_LENGTH 16	 			// 队列长度
#define ITEM_SIZE sizeof(char)		// 消息队列中传递的是一个字符串指针（地址），而不是字符串本身，处理效率较高
QueueHandle_t xQueue;
//volatile char[QUEUE_LENGTH];		// 不建议放在此处，多个任务同时访问会导致数据混乱

void vTask_LED_Controller(void *arg);
void vTask_USART_Handler(void *arg);

int main(void){
	USART1_TxRx_Init();  // 初始化 USB_TO_TTL
    USART1_Init();       // 初始化 传送字符格式
	USART1_NVIC_Init();  // 初始化 中断源优先级
	LED_Init();	     	 // 初始化 LED
	
	xQueue = xQueueCreate(8, QUEUE_LENGTH * ITEM_SIZE);
	
//	char test_str[] = "[TEST] main.c";		// 测试回收能否正常工作
//	xQueueSendFromISR(xQueue, test_str, NULL);
	
	xTaskCreate(vTask_USART_Handler, "vTask_UART_Handler", configMINIMAL_STACK_SIZE * 4, NULL, 1, NULL); 		// 启动调度程序	
	xTaskCreate(vTask_LED_Controller, "vTask_LED_Controller", configMINIMAL_STACK_SIZE * 4, NULL, 1, NULL);		// 串口任务优先级更低
 	vTaskStartScheduler();					// 启动调度器
	
	while(1);								// 程序不应执行到这里
}

void vReceiverTask(void *pvParameters)
{
    uint8_t ucReceivedValue;

    for (int i = 0; i < QUEUE_LENGTH; i++){
        // 尝试从队列中接收消息
        if (xQueueReceive(xQueue, &ucReceivedValue, portMAX_DELAY) == pdPASS){
            USART1_SendString("Queue recv fail. WTF! \r\n ");
        }
    }
}

// 串口任务（专注指令接收）
void vTask_USART_Handler(void *arg) {
	USART1_printf(
		"=== LED Controller ===\r\n"
		"COMMANDS:\r\n"
		"  OFF\\r    - Power off LED\r\n"
		"  ON\\r     - Power on LED\r\n"
		"  BLINK\\r  - Start blinking\r\n"
		"-----------------------\r\n"
		"Waiting for input...\r\n"
	);
	
    while(1);
}

// LED控制任务
void vTask_LED_Controller(void *arg) {	
//	char *ch;
	
    while(1) {
//		vReceiverTask(str);					// FreeRTOS任务函数必须通过xTaskCreate()启动，由系统调度，不能由别的任务中主动调用
		char str[QUEUE_LENGTH] = {0};
//		USART1_printf("[TEST] Run to main.c line 72 \r\n");
		
		if(xQueueReceive(xQueue, &str, 1000) == pdPASS){	// 写portMAX_DELAY会被持续阻塞
			USART1_printf("Receive the str: %s \r\n", str);
			LED_Control(str); 
		}else{
			USART1_printf("Not receive now \r\n");
		}
		
		vTaskDelay(1000);
//		USART1_printf("[TEST] Run to main.c line 82, delay done \r\n");
		
		if(current_state == LED_BLINK){
			LED_BlinkControl();
		}
	}
}
